import 'dart:math';

import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';

const titleColor = Color(0xff8c95db);

class HYScatterChartSamples extends StatefulWidget {
  const HYScatterChartSamples({Key? key}) : super(key: key);

  @override
  State<HYScatterChartSamples> createState() => _HYScatterChartSamplesState();
}

class _HYScatterChartSamplesState extends State<HYScatterChartSamples> {
  @override
  Widget build(BuildContext context) {
    return ListView(
      children: [
        Padding(
          padding: EdgeInsets.all(10).r,
          child: Column(
            children: [
              30.verticalSpace,
              const Text(
                "官方案例",
                style: TextStyle(
                  color: titleColor,
                  fontSize: 18,
                ),
              ),
              30.verticalSpace,
              const ScatterChartSample1(),
              30.verticalSpace,
              const ScatterChartSample2()
            ],
          ),
        )
      ],
    );
  }
}

class ScatterChartSample1 extends StatefulWidget {
  const ScatterChartSample1({Key? key}) : super(key: key);

  @override
  State<StatefulWidget> createState() => _ScatterChartSample1State();
}

class _ScatterChartSample1State extends State {
  final maxX = 50.0;
  final maxY = 50.0;
  final radius = 4.0;

  Color blue1 = const Color(0xFF0D47A1);
  Color blue2 = const Color(0xFF42A5F5).withOpacity(0.8);

  bool showFlutter = true;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        setState(() {
          showFlutter = !showFlutter;
        });
      },
      child: AspectRatio(
        aspectRatio: 1,
        child: Card(
          color: const Color(0xffffffff),
          elevation: 6,
          child: ScatterChart(
            ScatterChartData(
              scatterSpots: showFlutter ? flutterLogoData() : randomData(),
              minX: 0,
              maxX: maxX,
              minY: 0,
              maxY: maxY,
              borderData: FlBorderData(
                show: false,
              ),
              gridData: FlGridData(
                show: false,
              ),
              titlesData: FlTitlesData(
                show: false,
              ),
              scatterTouchData: ScatterTouchData(
                enabled: false,
              ),
            ),
            swapAnimationDuration: const Duration(milliseconds: 600),
            swapAnimationCurve: Curves.fastOutSlowIn,
          ),
        ),
      ),
    );
  }

  List<ScatterSpot> flutterLogoData() {
    return [
      /// section 1
      ScatterSpot(20, 14.5, color: blue1, radius: radius),
      ScatterSpot(22, 16.5, color: blue1, radius: radius),
      ScatterSpot(24, 18.5, color: blue1, radius: radius),

      ScatterSpot(22, 12.5, color: blue1, radius: radius),
      ScatterSpot(24, 14.5, color: blue1, radius: radius),
      ScatterSpot(26, 16.5, color: blue1, radius: radius),

      ScatterSpot(24, 10.5, color: blue1, radius: radius),
      ScatterSpot(26, 12.5, color: blue1, radius: radius),
      ScatterSpot(28, 14.5, color: blue1, radius: radius),

      ScatterSpot(26, 8.5, color: blue1, radius: radius),
      ScatterSpot(28, 10.5, color: blue1, radius: radius),
      ScatterSpot(30, 12.5, color: blue1, radius: radius),

      ScatterSpot(28, 6.5, color: blue1, radius: radius),
      ScatterSpot(30, 8.5, color: blue1, radius: radius),
      ScatterSpot(32, 10.5, color: blue1, radius: radius),

      ScatterSpot(30, 4.5, color: blue1, radius: radius),
      ScatterSpot(32, 6.5, color: blue1, radius: radius),
      ScatterSpot(34, 8.5, color: blue1, radius: radius),

      ScatterSpot(34, 4.5, color: blue1, radius: radius),
      ScatterSpot(36, 6.5, color: blue1, radius: radius),

      ScatterSpot(38, 4.5, color: blue1, radius: radius),

      /// section 2
      ScatterSpot(20, 14.5, color: blue2, radius: radius),
      ScatterSpot(22, 12.5, color: blue2, radius: radius),
      ScatterSpot(24, 10.5, color: blue2, radius: radius),

      ScatterSpot(22, 16.5, color: blue2, radius: radius),
      ScatterSpot(24, 14.5, color: blue2, radius: radius),
      ScatterSpot(26, 12.5, color: blue2, radius: radius),

      ScatterSpot(24, 18.5, color: blue2, radius: radius),
      ScatterSpot(26, 16.5, color: blue2, radius: radius),
      ScatterSpot(28, 14.5, color: blue2, radius: radius),

      ScatterSpot(26, 20.5, color: blue2, radius: radius),
      ScatterSpot(28, 18.5, color: blue2, radius: radius),
      ScatterSpot(30, 16.5, color: blue2, radius: radius),

      ScatterSpot(28, 22.5, color: blue2, radius: radius),
      ScatterSpot(30, 20.5, color: blue2, radius: radius),
      ScatterSpot(32, 18.5, color: blue2, radius: radius),

      ScatterSpot(30, 24.5, color: blue2, radius: radius),
      ScatterSpot(32, 22.5, color: blue2, radius: radius),
      ScatterSpot(34, 20.5, color: blue2, radius: radius),

      ScatterSpot(34, 24.5, color: blue2, radius: radius),
      ScatterSpot(36, 22.5, color: blue2, radius: radius),

      ScatterSpot(38, 24.5, color: blue2, radius: radius),

      /// section 3
      ScatterSpot(10, 25, color: blue2, radius: radius),
      ScatterSpot(12, 23, color: blue2, radius: radius),
      ScatterSpot(14, 21, color: blue2, radius: radius),

      ScatterSpot(12, 27, color: blue2, radius: radius),
      ScatterSpot(14, 25, color: blue2, radius: radius),
      ScatterSpot(16, 23, color: blue2, radius: radius),

      ScatterSpot(14, 29, color: blue2, radius: radius),
      ScatterSpot(16, 27, color: blue2, radius: radius),
      ScatterSpot(18, 25, color: blue2, radius: radius),

      ScatterSpot(16, 31, color: blue2, radius: radius),
      ScatterSpot(18, 29, color: blue2, radius: radius),
      ScatterSpot(20, 27, color: blue2, radius: radius),

      ScatterSpot(18, 33, color: blue2, radius: radius),
      ScatterSpot(20, 31, color: blue2, radius: radius),
      ScatterSpot(22, 29, color: blue2, radius: radius),

      ScatterSpot(20, 35, color: blue2, radius: radius),
      ScatterSpot(22, 33, color: blue2, radius: radius),
      ScatterSpot(24, 31, color: blue2, radius: radius),

      ScatterSpot(22, 37, color: blue2, radius: radius),
      ScatterSpot(24, 35, color: blue2, radius: radius),
      ScatterSpot(26, 33, color: blue2, radius: radius),

      ScatterSpot(24, 39, color: blue2, radius: radius),
      ScatterSpot(26, 37, color: blue2, radius: radius),
      ScatterSpot(28, 35, color: blue2, radius: radius),

      ScatterSpot(26, 41, color: blue2, radius: radius),
      ScatterSpot(28, 39, color: blue2, radius: radius),
      ScatterSpot(30, 37, color: blue2, radius: radius),

      ScatterSpot(28, 43, color: blue2, radius: radius),
      ScatterSpot(30, 41, color: blue2, radius: radius),
      ScatterSpot(32, 39, color: blue2, radius: radius),

      ScatterSpot(30, 45, color: blue2, radius: radius),
      ScatterSpot(32, 43, color: blue2, radius: radius),
      ScatterSpot(34, 41, color: blue2, radius: radius),

      ScatterSpot(34, 45, color: blue2, radius: radius),
      ScatterSpot(36, 43, color: blue2, radius: radius),

      ScatterSpot(38, 45, color: blue2, radius: radius),
    ];
  }

  List<ScatterSpot> randomData() {
    const blue1Count = 21;
    const blue2Count = 57;
    return List.generate(blue1Count + blue2Count, (i) {
      Color color;
      if (i < blue1Count) {
        color = blue1;
      } else {
        color = blue2;
      }

      return ScatterSpot(
        (Random().nextDouble() * (maxX - 8)) + 4,
        (Random().nextDouble() * (maxY - 8)) + 4,
        color: color,
        radius: (Random().nextDouble() * 16) + 4,
      );
    });
  }
}

class ScatterChartSample2 extends StatefulWidget {
  const ScatterChartSample2({Key? key}) : super(key: key);

  @override
  State<StatefulWidget> createState() => _ScatterChartSample2State();
}

class _ScatterChartSample2State extends State {
  int touchedIndex = -1;

  Color greyColor = Colors.grey;

  List<int> selectedSpots = [];

  @override
  Widget build(BuildContext context) {
    return AspectRatio(
      aspectRatio: 1,
      child: Card(
        color: const Color(0xff222222),
        child: ScatterChart(
          ScatterChartData(
            scatterSpots: [
              ScatterSpot(
                4,
                4,
                color: selectedSpots.contains(0) ? Colors.green : greyColor,
              ),
              ScatterSpot(
                2,
                5,
                color: selectedSpots.contains(1) ? Colors.yellow : greyColor,
                radius: 12,
              ),
              ScatterSpot(
                4,
                5,
                color:
                    selectedSpots.contains(2) ? Colors.purpleAccent : greyColor,
                radius: 8,
              ),
              ScatterSpot(
                8,
                6,
                color: selectedSpots.contains(3) ? Colors.orange : greyColor,
                radius: 20,
              ),
              ScatterSpot(
                5,
                7,
                color: selectedSpots.contains(4) ? Colors.brown : greyColor,
                radius: 14,
              ),
              ScatterSpot(
                7,
                2,
                color: selectedSpots.contains(5)
                    ? Colors.lightGreenAccent
                    : greyColor,
                radius: 18,
              ),
              ScatterSpot(
                3,
                2,
                color: selectedSpots.contains(6) ? Colors.red : greyColor,
                radius: 36,
              ),
              ScatterSpot(
                2,
                8,
                color:
                    selectedSpots.contains(7) ? Colors.tealAccent : greyColor,
                radius: 22,
              ),
            ],
            minX: 0,
            maxX: 10,
            minY: 0,
            maxY: 10,
            borderData: FlBorderData(
              show: false,
            ),
            gridData: FlGridData(
              show: true,
              drawHorizontalLine: true,
              checkToShowHorizontalLine: (value) => true,
              getDrawingHorizontalLine: (value) =>
                  FlLine(color: Colors.white.withOpacity(0.1)),
              drawVerticalLine: true,
              checkToShowVerticalLine: (value) => true,
              getDrawingVerticalLine: (value) =>
                  FlLine(color: Colors.white.withOpacity(0.1)),
            ),
            titlesData: FlTitlesData(
              show: false,
            ),
            showingTooltipIndicators: selectedSpots,
            scatterTouchData: ScatterTouchData(
              enabled: true,
              handleBuiltInTouches: false,
              mouseCursorResolver:
                  (FlTouchEvent touchEvent, ScatterTouchResponse? response) {
                return response == null || response.touchedSpot == null
                    ? MouseCursor.defer
                    : SystemMouseCursors.click;
              },
              touchTooltipData: ScatterTouchTooltipData(
                tooltipBgColor: Colors.black,
                getTooltipItems: (ScatterSpot touchedBarSpot) {
                  return ScatterTooltipItem(
                    'X: ',
                    textStyle: TextStyle(
                      height: 1.2,
                      color: Colors.grey[100],
                      fontStyle: FontStyle.italic,
                    ),
                    bottomMargin: 10,
                    children: [
                      TextSpan(
                        text: '${touchedBarSpot.x.toInt()} \n',
                        style: const TextStyle(
                          color: Colors.white,
                          fontStyle: FontStyle.normal,
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                      TextSpan(
                        text: 'Y: ',
                        style: TextStyle(
                          height: 1.2,
                          color: Colors.grey[100],
                          fontStyle: FontStyle.italic,
                        ),
                      ),
                      TextSpan(
                        text: touchedBarSpot.y.toInt().toString(),
                        style: const TextStyle(
                          color: Colors.white,
                          fontStyle: FontStyle.normal,
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                    ],
                  );
                },
              ),
              touchCallback:
                  (FlTouchEvent event, ScatterTouchResponse? touchResponse) {
                if (touchResponse == null ||
                    touchResponse.touchedSpot == null) {
                  return;
                }
                if (event is FlTapUpEvent) {
                  final sectionIndex = touchResponse.touchedSpot!.spotIndex;
                  setState(() {
                    if (selectedSpots.contains(sectionIndex)) {
                      selectedSpots.remove(sectionIndex);
                    } else {
                      selectedSpots.add(sectionIndex);
                    }
                  });
                }
              },
            ),
          ),
        ),
      ),
    );
  }
}
